package jp.anago_dev.takarush_helper.ui.actionbar;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import jp.anago_dev.takarush_helper.R;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.app.Activity;
import android.content.Context;
import android.content.res.XmlResourceParser;
import android.os.Bundle;
import android.view.InflateException;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

/**
 * アクションバーのベースとなります。<br/>
 * パッケージ外部からは参照されません。
 * 
 * @author anago_dev
 * 
 */
final class ActionBarHelperBase extends ActionBarHelper {

    /** name space */
    private static final String MENU_RES_NAMESPACE = "http://schemas.android.com/apk/res/android";

    /** ID */
    private static final String MENU_ATTR_ID = "id";

    /** showAsAction */
    private static final String MENU_ATTR_SHOW_AS_ACTION = "showAsAction";

    /** アクションアイテムID */
    protected Set<Integer> mActionItemIds = new HashSet<Integer>();

    protected ActionBarHelperBase(Activity activity) {
        super(activity);
    }

    /**
     * @see jp.anago_dev.takarush_helper.ui.actionbar.ActionBarHelper#onCreate(android.os.Bundle)
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        mActivity.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);

    }

    /**
     * @see jp.anago_dev.takarush_helper.ui.actionbar.ActionBarHelper#onPostCreate(android.os.Bundle)
     */
    @Override
    public void onPostCreate(Bundle savedInstanceState) {
        mActivity.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.actionbar_compat);
        setupActionBar();

        // メニュー構築
        SimpleMenu menu = new SimpleMenu(mActivity);
        mActivity.onCreatePanelMenu(Window.FEATURE_OPTIONS_PANEL, menu);
        mActivity.onPrepareOptionsMenu(menu);
        for (int i = 0; i < menu.size(); i++) {
            MenuItem item = menu.getItem(i);
            if (mActionItemIds.contains(item.getItemId())) {
                addActionItemCompatFromMenuItem(item);
            }
        }

    }

    /**
     * アクションバーを構築します。
     */
    private void setupActionBar() {
        final ViewGroup actionBarCompat = getActionBarCompat();
        if (actionBarCompat == null) {
            return;
        }

        LinearLayout.LayoutParams springLayoutParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT);
        springLayoutParams.weight = 1;

        // ホームボタンの追加
        SimpleMenu tempMenu = new SimpleMenu(mActivity);
        SimpleMenuItem homeItem = new SimpleMenuItem(tempMenu, android.R.id.home, 0, mActivity.getString(R.string.app_name));
        homeItem.setIcon(R.drawable.ic_home);
        addActionItemCompatFromMenuItem(homeItem);

        // タイトルの追加
        TextView titleText = new TextView(mActivity, null, R.attr.actionbarCompatTitleStyle);
        titleText.setLayoutParams(springLayoutParams);
        titleText.setText(mActivity.getTitle());
        actionBarCompat.addView(titleText);
    }

    private ViewGroup getActionBarCompat() {
        return (ViewGroup) mActivity.findViewById(R.id.actionbar_compat);
    }

    /**
     * メニュー項目を使用してアクションボタンを構築します。<br/>
     * TODO:要カスタマイズ
     */
    private View addActionItemCompatFromMenuItem(final MenuItem item) {
        final int itemId = item.getItemId();

        final ViewGroup actionBar = getActionBarCompat();
        if (actionBar == null) {
            return null;
        }

        // Create the button
        ImageButton actionButton = new ImageButton(mActivity, null, itemId == android.R.id.home ? R.attr.actionbarCompatItemHomeStyle : R.attr.actionbarCompatItemStyle);
        actionButton.setLayoutParams(new ViewGroup.LayoutParams((int) mActivity.getResources().getDimension(itemId == android.R.id.home ? R.dimen.actionbar_compat_button_home_width : R.dimen.actionbar_compat_button_width), ViewGroup.LayoutParams.FILL_PARENT));
        // if (itemId == R.id.menu_my_location) {
        // actionButton.setId(R.id.actionbar_compat_item_refresh);
        // }
        actionButton.setImageDrawable(item.getIcon());
        actionButton.setScaleType(ImageView.ScaleType.CENTER);
        actionButton.setContentDescription(item.getTitle());
        actionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mActivity.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, item);
            }
        });

        actionBar.addView(actionButton);

//        // インジケータ表示
//        if (item.getItemId() == R.id.menu_my_location) {
//            // Refresh buttons should be stateful, and allow for indeterminate
//            // progress indicators,
//            // so add those.
//            ProgressBar indicator = new ProgressBar(mActivity, null, R.attr.actionbarCompatProgressIndicatorStyle);
//
//            final int buttonWidth = mActivity.getResources().getDimensionPixelSize(R.dimen.actionbar_compat_button_width);
//            final int buttonHeight = mActivity.getResources().getDimensionPixelSize(R.dimen.actionbar_compat_height);
//            final int progressIndicatorWidth = buttonWidth / 2;
//
//            final LinearLayout.LayoutParams indicatorLayoutParams = new LinearLayout.LayoutParams(progressIndicatorWidth, progressIndicatorWidth);
//            indicatorLayoutParams.setMargins((buttonWidth - progressIndicatorWidth) / 2, (buttonHeight - progressIndicatorWidth) / 2, (buttonWidth - progressIndicatorWidth) / 2, 0);
//            indicator.setLayoutParams(indicatorLayoutParams);
//            indicator.setVisibility(View.GONE);
//            indicator.setId(R.id.actionbar_compat_item_refresh_progress);
//            indicator.setOnClickListener(new View.OnClickListener() {
//                @Override
//                public void onClick(View view) {
//                    mActivity.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, item);
//                }
//            });
//            actionBar.addView(indicator);
//        }

        return actionButton;
    }

    /**
     * @see jp.anago_dev.takarush_helper.ui.actionbar.ActionBarHelper#setRefreshActionItemState(boolean)
     */
    @Override
    public void setRefreshActionItemState(boolean refreshing) {

        // TODO: 本アプリはリフレッシュの意味合いが無いので修正
        View refreshButton = mActivity.findViewById(R.id.actionbar_compat_item_refresh);
        View refreshIndicator = mActivity.findViewById(R.id.actionbar_compat_item_refresh_progress);

        if (refreshButton != null) {
            refreshButton.setVisibility(refreshing ? View.GONE : View.VISIBLE);
        }
        if (refreshIndicator != null) {
            refreshIndicator.setVisibility(refreshing ? View.VISIBLE : View.GONE);
        }
    }

    /**
     * @see jp.anago_dev.takarush_helper.ui.actionbar.ActionBarHelper#onCreateOptionsMenu(android.view.Menu)
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // オプションメニューからスクリーン上のアクションアイテムを隠蔽
        for (Integer id : mActionItemIds) {
            menu.findItem(id).setVisible(false);
        }
        return true;
    }

    /**
     * @see jp.anago_dev.takarush_helper.ui.actionbar.ActionBarHelper#onTitleChanged(java.lang.CharSequence,
     *      int)
     */
    @Override
    public void onTitleChanged(CharSequence title, int color) {
        TextView titleView = (TextView) mActivity.findViewById(R.id.actionbar_compat_title);
        if (titleView != null) {
            titleView.setText(title);
        }
    }

    /**
     * @see jp.anago_dev.takarush_helper.ui.actionbar.ActionBarHelper#getMenuInflater(android.view.MenuInflater)
     */
    @Override
    protected MenuInflater getMenuInflater(MenuInflater superMenuInflater) {
        return new WrappedMenuInflater(mActivity, superMenuInflater);
    }

    private class WrappedMenuInflater extends MenuInflater {

        MenuInflater mInflater;

        public WrappedMenuInflater(Context context, MenuInflater inflater) {
            super(context);
            mInflater = inflater;
        }

        @Override
        public void inflate(int menuRes, Menu menu) {
            loadActionBarMetadata(menuRes);
            mInflater.inflate(menuRes, menu);
        }

        /**
         * XMLのメタデータ(ICSからの追加項目など)を読み込みます。
         * 
         * Loads action bar metadata from a menu resource, storing a list of
         * menu item IDs that should be shown on-screen (i.e. those with
         * showAsAction set to always or ifRoom).
         * 
         * @param menuResId
         */
        private void loadActionBarMetadata(int menuResId) {
            XmlResourceParser parser = null;
            try {
                parser = mActivity.getResources().getXml(menuResId);

                int eventType = parser.getEventType();
                int itemId;
                int showAsAction;

                boolean eof = false;
                while (!eof) {
                    switch (eventType) {
                    case XmlPullParser.START_TAG:
                        if (!parser.getName().equals("item")) {
                            break;
                        }

                        itemId = parser.getAttributeResourceValue(MENU_RES_NAMESPACE, MENU_ATTR_ID, 0);
                        if (itemId == 0) {
                            break;
                        }

                        showAsAction = parser.getAttributeIntValue(MENU_RES_NAMESPACE, MENU_ATTR_SHOW_AS_ACTION, -1);
                        if (showAsAction == MenuItem.SHOW_AS_ACTION_ALWAYS || showAsAction == MenuItem.SHOW_AS_ACTION_IF_ROOM) {
                            mActionItemIds.add(itemId);
                        }
                        break;

                    case XmlPullParser.END_DOCUMENT:
                        eof = true;
                        break;
                    }

                    eventType = parser.next();
                }
            } catch (XmlPullParserException e) {
                throw new InflateException("Error inflating menu XML", e);
            } catch (IOException e) {
                throw new InflateException("Error inflating menu XML", e);
            } finally {
                if (parser != null) {
                    parser.close();
                }
            }
        }

    }

}
